package in.animeshpathak.saferstreets;

import in.animeshpathak.saferstreets.models.IncidentReport;
import in.animeshpathak.saferstreets.models.PMF;
import in.animeshpathak.saferstreets.models.SaferStreetsUser;

import java.io.IOException;
import java.util.Date;
import java.util.List;

import javax.jdo.PersistenceManager;
import javax.jdo.Transaction;
import javax.servlet.http.*;

import org.apache.velocity.VelocityContext;

import com.beoui.geocell.GeocellManager;
import com.beoui.geocell.model.Point;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;

import org.apache.commons.lang.StringEscapeUtils;

@SuppressWarnings("serial")
public class UploadServlet extends HttpServlet {

	PersistenceManager pm;

	@Override
	public void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws IOException {

		UserService userService = UserServiceFactory.getUserService();


		if (req.getUserPrincipal() == null) {
			resp.sendRedirect(userService.createLoginURL(req.getRequestURI()));
		} else {

			/*  create a context and add data */
			VelocityContext context = new VelocityContext();
			context.put("logouturl", userService.createLogoutURL(req.getRequestURI()));
			context.put("user_nick", userService.getCurrentUser().getNickname());

			Utils.renderTemplate("res/upload-form.html", resp, context);
		}

	}

	@Override
	public void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws IOException {
		UserService userService = UserServiceFactory.getUserService();


		//TODO catch exceptions here, report errors.
		double longitude = Double.parseDouble(req.getParameter("longitude"));
		double latitude = Double.parseDouble(req.getParameter("latitude"));
		double altitude = 0;
		double accuracy = Double.parseDouble(req.getParameter("accuracy"));
		//TODO sanitize this string properly!
		String incidentType = StringEscapeUtils.escapeHtml(req.getParameter("incidentType"));
		boolean showId = ("yes".equals(req.getParameter("showId")));

		// Transform it to a point
		Point p = new Point(latitude, longitude);

		// Generates the list of GeoCells
		List<String> cells = GeocellManager.generateGeoCell(p);

		//get the user.
		//SaferStreetsUser thisUser = getOrCreateUser(userService.getCurrentUser());

		pm = PMF.get().getPersistenceManager();
		Transaction tx = pm.currentTransaction();

		try{
			
			tx.begin();
			
			
			IncidentReport newReport = new IncidentReport(longitude, latitude, cells, altitude, 
					accuracy, incidentType, new Date(), userService.getCurrentUser(), showId);

//			SaferStreetsUser tempUser, retUser;
//			User user = userService.getCurrentUser();
//			String userId = user.getUserId();
			
//			
//			try{
//				tempUser = pm.getObjectById(SaferStreetsUser.class, userId);
//
//			}  	catch (Exception e){
//				//oops, user not in datastore, make a new one.
//
//				tempUser = new SaferStreetsUser(user, userId);
//				pm.makePersistent(tempUser);
//			}

			//newReport.setreporter(tempUser);
			
			pm.makePersistent(newReport);
			tx.commit();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (tx.isActive())
		    {
		        // Error occurred so rollback the transaction
		        tx.rollback();
		    }
			pm.close();
		}

		/*  create a context and add data */
		VelocityContext context = new VelocityContext();

		context.put("logouturl", userService.createLogoutURL(req.getRequestURI()));
		context.put("latitude", latitude);
		context.put("longitude", longitude);
		context.put("accuracy", accuracy);
		context.put("incidentType", incidentType);
		context.put("showId", showId);
		context.put("user", userService.getCurrentUser());

		Utils.renderTemplate("res/upload-result.html", resp, context);
	}


	/**
	 * returns the {@link SaferStreetsUser} object corresponding to a given {@link User}. 
	 * Creates a new persistant object if required. 
	 * @param u The user object from GAE
	 * @return the SaferStreetsUser object corresponding to this GAE user
	 */
	private SaferStreetsUser getOrCreateUser(User u){
		SaferStreetsUser tempUser, retUser;

		pm = PMF.get().getPersistenceManager();

		try{

			try{
				tempUser = pm.getObjectById(SaferStreetsUser.class, u.getUserId());

			}  	catch (Exception e){
				//oops, user not in datastore, make a new one.

				tempUser = new SaferStreetsUser(u, u.getUserId());
				pm.makePersistent(tempUser);
			}
			
			retUser = pm.detachCopy(tempUser);

		} finally {
			pm.close();
		}

		return retUser;


	}

}
